package com.hexb.arithmetic.llk
{
	public class ConnectArithmeticImpl implements IConnectArithmetic
	{
		private var path:Array = new Array(4);
		public static var instance:IConnectArithmetic = new ConnectArithmeticImpl();

		public function hasConnectPath(p1:LPoint, p2:LPoint, snapshot:Array):Boolean
		{
			clearPath();
			if(inSameLine(p1,p2,snapshot)){
				return true ;
			}
			clearPath();
			if(oneCorner(p1,p2,snapshot)){
				return true ;
			}
			clearPath();
			if(towCorner(p1,p2,snapshot)){
				return true;
			}
			clearPath();
			return false ;
		}
		
		public function getConnectPath():Array{
			return path ;
		}
		/**
		 * 判断是否可以两折相连
		 * */
		private function towCorner(p1:LPoint, p2:LPoint, snapshot:Array):Boolean{
			var result:Boolean = false;
			if(p2.col <= p1.col){
				result = towCornerRightAndLeft(p2,p1,snapshot,1) ;
				if(result){
					return true ;
				}
			}else{
				result = towCornerRightAndLeft(p1,p2,snapshot,1);
				if(result){
					return true ;
				}
			}
			if(p2.col >= p1.col){
				result = towCornerRightAndLeft(p2,p1,snapshot,-1);
				if(result){
					return true ;
				}
			}else{
				result = towCornerRightAndLeft(p1,p2,snapshot,-1) ;
				if(result){
					return true ;
				}
			}
			if(p2.row <= p1.row){
				result = towCornerTopAndBottom(p1,p2,snapshot,1) ;
				if(result){
					return true ;
				}
			}else{
				result = towCornerTopAndBottom(p2,p1,snapshot,1) ;
				if(result){
					return true ;
				}
			}
			if(p2.row >= p1.row){
				result = towCornerTopAndBottom(p2,p1,snapshot,-1) ;
				if(result){
					return true ;
				}
			}else{
				result = towCornerTopAndBottom(p1,p2,snapshot,-1) ;
				if(result){
					return true ;
				}
			}
			return false;
		}
		
		/**传入的p1,p2相应的列已经为排列好大小顺序的列*/
		private function towCornerRightAndLeft(p1:LPoint,p2:LPoint,snapshot:Array,direction:int):Boolean{
			var colNum:int = (snapshot[0] as Array).length;
			var i:int ;
			var tempPointA:LPoint ;
			var tempPointB:LPoint ;
			var temp:Boolean ;
			for(i= p1.col+direction ;i<colNum&&i>=0 ;i+=direction){
				if(snapshot[p1.row][i]==1 || snapshot[p2.row][i]==1 || inSameLine(new LPoint(p2.row,i),p2,snapshot)==false){
					return false ;
				}
				tempPointA = new LPoint(p1.row,i);
				tempPointB = new LPoint(p2.row,i);
				temp = inSameLine(tempPointA,tempPointB,snapshot) ;
				if(temp==true){
					path[0] = p1 ;
					path[1] = tempPointA ;
					path[2] = tempPointB ;
					path[3] = p2 ;
					return true ;
				}
			}
			return false;
		}
		
		/**传入的p1,p2相应的列已经为排列好大小顺序的列*/
		private function towCornerTopAndBottom(p1:LPoint,p2:LPoint,snapshot:Array,direction:int):Boolean{
			var rowNum:int = snapshot.length;
			var i:int ;
			var tempPointA:LPoint ;
			var tempPointB:LPoint ;
			var temp:Boolean ;
			for(i=p1.row+direction;i<rowNum && i>=0 ;i+=direction){
				if(snapshot[i][p1.col]==1 || snapshot[i][p2.col]==1 || inSameLine(new LPoint(i,p2.col),p2,snapshot)==false){
					return false ;
				}
				tempPointA = new LPoint(i,p1.col);
				tempPointB = new LPoint(i,p2.col);
				temp = inSameLine(tempPointA,tempPointB,snapshot) ;
				if(temp==true){
					path[0] = p1 ;
					path[1] = tempPointA ;
					path[2] = tempPointB ;
					path[3] = p2 ;
					return true ;
				}
			}
			return false;
		}
		
		
		/**
		 * 判断是否可以一折相连
		 * */
		private function oneCorner(p1:LPoint, p2:LPoint, snapshot:Array):Boolean{
			//找出两个中间点
			var tempPoint4One:LPoint = new LPoint(p1.row,p2.col);
			var tempPoint4Two:LPoint = new LPoint(p2.row,p1.col);
			
			if(inSameLine(p1,tempPoint4One,snapshot) && inSameLine(tempPoint4One,p2,snapshot)){
				path[0] = p1 ;
				path[1] = tempPoint4One ;
				path[3] = p2 ;
				return true ;
			}
			if(inSameLine(p1,tempPoint4Two,snapshot) && inSameLine(tempPoint4Two,p2,snapshot)){
				path[0] = p1 ;
				path[1] = tempPoint4Two ;
				path[3] = p2 ;
				return true ;
			}
			path[1] = null ;
			return false ;
		}

		/**
		 * 
		 **/
		private function inSameLine(p1:LPoint,p2:LPoint,sanpshot:Array):Boolean{
			if(p1.col == p2.col){
				path[0] = p1 ;
				path[3] = p2 ;
				return sameColCanConnect(p1,p2,sanpshot);
			}
			if(p1.row == p2.row){
				path[0] = p1 ;
				path[3] = p2 ;
				return sameRowCanConnect(p1,p2,sanpshot);
			}
			return false;
		}
		
		
		/**
		 * 直线-同一行
		 **/
		private function sameRowCanConnect(p1:LPoint,p2:LPoint,sanpshot:Array):Boolean{
			var startCol:int = p1.col < p2.col ? p1.col : p2.col ;
			var endCol:int = p1.col > p2.col ? p1.col : p2.col;
			var row:int = p1.row ;
			
			var i:int ;
			for(i = startCol+1 ;i<endCol ;i++){
				if(sanpshot[row][i]==1){
					return false;
				}
			}
			return true ;
		}
		
		/**
		 * 直线-同一列
		 **/
		private function sameColCanConnect(p1:LPoint,p2:LPoint,sanpshot:Array):Boolean{
			var startRow:int = p1.row < p2.row ? p1.row : p2.row ;
			var endRow:int = p1.row > p2.row ? p1.row : p2.row;
			var col:int = p1.col ;
			var i:int ;
			for(i = startRow+1 ;i<endRow ;i++){
				if(sanpshot[i][col]==1){
					return false ;
				}
			}
			return true ;
		}
		
		private function clearPath():void{
			path[0] = null ;
			path[1] = null ;
			path[2] = null ;
			path[3] = null ;
		}
		
		public function ConnectArithmeticImpl()
		{
		}
	}
}